<template>
  <div>
    <el-steps :active="step" finish-status="success" process-status="finish" simple>
      <el-step title="密保邮箱" ></el-step>
      <el-step title="邮箱验证" ></el-step>
      <el-step title="修改密码" ></el-step>
    </el-steps>

    <el-form ref="ruleForm" :model="ruleForm" :rules="rules" label-width="75px">

      <el-form-item v-if="step === 0" label="邮箱" prop="mail">
        <el-input v-model="ruleForm.mail" type="text"></el-input>
      </el-form-item>

      <el-form-item v-if="step === 1" label="验证码" prop="code">
        <el-input v-model="ruleForm.code" type="text"></el-input>
      </el-form-item>

      <el-form-item v-if="step === 2" label="密码" prop="pass">
        <el-input v-model="ruleForm.pass" autocomplete="off"
                  show-password type="password"></el-input>
      </el-form-item>

      <el-form-item v-if="step === 2" label="确认密码" prop="checkPass">
        <el-input v-model="ruleForm.checkPass" autocomplete="off" type="password"></el-input>
      </el-form-item>

    </el-form>

    <el-button-group>
      <el-button v-show="step!==2" icon="el-icon-arrow-left" @click="toPre">上一步</el-button>
      <el-button :disabled="isWaiting" :loading="isSending"
                 type="primary" @click="submit">
        <span :class="{wordTips: isWaiting}">{{sendTipText}}</span>
        <i v-show="!isWaiting || isNxtBtnVis" class="el-icon-arrow-right el-icon--right"/>
      </el-button>
      <el-button v-show="isNxtBtnVis" type="primary" @click="toNext">
        下一步
        <i class="el-icon-arrow-right el-icon--right"/>
      </el-button>
    </el-button-group>
  </div>
</template>

<script>
import encrypt from "@/mixin/encrypt";
export default {
  name: "ForgetPassword",
  data() {
    const validateMail = (rule, value, callback) => {
      value = value.trim();
      if (value === '') {
        callback(new Error('邮箱账号不能为空'));
      } else {
        const reg = /^[\w\u4e00-\u9fa5-]+@\w+\.+\w{2,}$/g;
        if (!reg.test(value)) {
          callback(new Error('请输入有效的邮箱地址'));
        } else callback();
      }
    };
    const validateCode = async (rule, value, callback) => {
      value = value.trim();
      if (value === '') {
        callback(new Error('验证码不能为空'));
      } else {
        try {
          const res = await this.$axios.get(this.$store.state.serverUrl+'/api/verify', {
            params: {address: this.ruleForm.mail, ver: this.ruleForm.code}
          });
          if (res.data.status !== 0) {
            callback(new Error(res.data.msg));
          } else callback();
        } catch (err) {
          await this.$alert(err.message, '网络连接出错')
          callback(new Error('请稍后重试'))
        }
      }
    };
    const validatePass = (rule, value, callback) => {
      if (value === '') {
        callback(new Error('密码不能为空'));
      } else {
        const reg = /^\w{8,16}$/;
        if (!reg.test(value)) {
          callback(new Error('请输入仅包含数字和英文字母在内的8-16为密码'));
        } else {
          if (this.ruleForm.checkPass !== '') {
            this.$refs.ruleForm.validateField('checkPass');
          }
          callback();
        }
      }
    };
    const validatePass2 = (rule, value, callback) => {
      if (value === '') {
        callback(new Error('请再次输入密码'));
      } else if (value !== this.ruleForm.pass) {
        callback(new Error('两次输入密码不一致!'));
      } else {
        callback();
      }
    };
    return {
      step: 0,

      ruleForm: {
        mail: '',
        code: '',
        pass: '',
        checkPass: '',
      },
      rules: {
        mail: [{ validator: validateMail, trigger: 'none' }],
        code: [{ validator: validateCode, trigger: 'none' }],
        pass: [{ validator: validatePass, trigger: 'blur' }],
        checkPass: [{ validator: validatePass2, trigger: 'blur' }],
      },
      count: 0,
      isSending: false,
      isSent: false,
    }
  },
  computed: {
    sendTipText() {
      switch (this.step) {
        case 0: {
          if (this.isSending) return '发送中……'
          if (this.count > 0) return `重新发送 (${this.count}s)`
          else return '发送验证码'
        }

        case 1:
          return '校验验证码'

        case 2:
          return '保存修改'

        default:
          throw new Error('step out of range')
      }
    },
    isWaiting() {
      return this.step === 0 && this.count > 0
    },
    isNxtBtnVis() {
      return this.step === 0 && this.isSent
    }
  },
  mixins: [encrypt],
  methods: {
    countDown() {
      if (this.count > 0) {
        this.count--;
        setTimeout(this.countDown, 1000);
      }
    },
    toPre() {
      if (this.step > 0) this.step--;
      else this.$emit('finishChange');
    },
    toNext() {
      this.step++;
    },
    submit() {
      switch (this.step) {
        case 0: {
          this.$refs.ruleForm.validateField('mail', err => {
            if (!err) {
              this.isSending = true;
              this.$axios.get(this.$store.state.serverUrl+'/api/sendMail', {
                params: {mail: this.ruleForm.mail}
              }).then(res => {
                this.isSending = false;
                if (res.data.status !== 0) {
                  this.$alert(res.data.msg, '验证码发送失败')
                } else {
                  this.$message.success('验证码已发送');
                  this.count = 61;
                  this.countDown();
                  this.isSent = true;
                }
              }).catch(err => {
                this.$alert(err.message, '网络连接出错');
                this.isSending = false;
              })
            }
          });
          break;
        }

        case 1: {
          this.$refs.ruleForm.validateField('code', err => {
            if (!err) {
              this.$message.success('验证码校验成功！');
              this.toNext();
            }
          });
          break;
        }

        case 2: {
          let valid = true;
          this.$refs.ruleForm.validateField(['pass', 'checkPass'], err => {
            if (err) valid = false;
          });
          if (valid) {
            (async () => {
              try {
                const encrypted = await this.encrypt(this.ruleForm.pass);

                try {
                  const res = await this.$axios.put(this.$store.state.serverUrl+'/api/changePassword', {
                    mail:this.ruleForm.mail, newPass: encrypted,
                  });
                  if (res.data.status !== 0) {
                    await this.$alert(res.data.msg, '修改失败');
                  } else {
                    this.$message.success('修改成功');
                    this.$emit('finishChange');
                  }
                } catch (err) {
                  await this.$alert(err.message, '网络连接出错')
                }
              } catch (err) {
                await this.$alert(err.message, '加密失败');
              }
            })()
          }
        }
      }
    },
  }
}
</script>

<style lang="scss" scoped>
  .el-button-group {
    position: relative;
    left: 100%;
    transform: translateX(-100%);
  }
  .el-form {
    margin-top: 5%;
  }
</style>